/***********************************************************************************
 * 文件名： polsys.h
 * 版本： 2
 * 说明：
 * 		polsys 核心实现。 
 *      【polsys】
 *      使用软定时器原理的“多任务”系统, 轮询调用入口函数，非RTOS。支持在任意地方创建任务。
 *      【polsys_lite】
 *      通过在用户端提供宏定义配置的方式让用户添加几个固定间隔时间需要执行的任务函数，然后在
 *  Polsys_Loop 定时调用他们。 这样的机制可以在不支持函数指针的“低端RISC 8位单片机”中帮助代
 *  码去耦，让软件更具模块化和面向对象。
 *      main.c 文件中已经编写好程序入口函数，用户只需要将main.c添加到工程即可。然后还需要
 *  在一个定时器中断中调用 Polsys_Tick() ，详见头文件。
 * 修改记录：
 * 	2021/04/28: 初版。 刘言。
 *  2021/05/19：合并polsys。刘言。
***********************************************************************************/
#ifndef _POLSYS_H_
#define _POLSYS_H_

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <math.h>
#ifdef __NO_INCLUDE_PATH // 如果有，定义在 stddef.h
#include "..\projects\prj\app\polsys_config.h"
#else
#include "a-polsys_config.h"
#endif
#include "polsys_mcu.h"

#ifdef POLSYS_LITE

// 仅为了伪函数优化曝光以下属性，用户不应该直接访问。

extern bit _Polsys_mTicked;
#ifdef _POLSYS_TASK_GROUP_1000TICK
extern u8 _Polsys_TickCount;
extern u8 _Polsys_10TickCount;
extern u8 _Polsys_100TickCount;
#elif (defined _POLSYS_TASK_GROUP_100TICK)
extern u8 _Polsys_TickCount;
extern u8 _Polsys_10TickCount;
#elif (defined _POLSYS_TASK_GROUP_10TICK)
extern u8 _Polsys_TickCount;
#endif

// 为了将 Polsys_Loop 函数定义成伪函数，才有了下面这一大推预处理

#if (defined _POLSYS_TASK_GROUP_10TICK) || (defined _POLSYS_TASK_GROUP_100TICK) || (defined _POLSYS_TASK_GROUP_1000TICK)
#ifdef _POLSYS_TASK_GROUP_10TICK
#define _Polsys_Do10TickTask() _POLSYS_TASK_GROUP_10TICK
#else
#define _Polsys_Do10TickTask()
#endif
#if (defined _POLSYS_TASK_GROUP_100TICK) || (defined _POLSYS_TASK_GROUP_1000TICK)
#ifdef _POLSYS_TASK_GROUP_100TICK
#define _Polsys_Do100TickTask() _POLSYS_TASK_GROUP_100TICK
#else
#define _Polsys_Do100TickTask()
#endif
#ifdef _POLSYS_TASK_GROUP_1000TICK
#define _Polsys_1000TickProcess()        \
    {                                    \
        _Polsys_100TickCount++;          \
        if (_Polsys_100TickCount == 10)  \
        {                                \
            _POLSYS_TASK_GROUP_1000TICK; \
            _Polsys_100TickCount = 0;    \
        }                                \
    }
#else
#define _Polsys_1000TickProcess()
#endif
#define _Polsys_100TickProcess()       \
    {                                  \
        _Polsys_10TickCount++;         \
        if (_Polsys_10TickCount == 10) \
        {                              \
            _Polsys_Do100TickTask();   \
            _Polsys_10TickCount = 0;   \
            _Polsys_1000TickProcess(); \
        }                              \
    }
#else
#define _Polsys_100TickProcess()
#endif
#define _Polsys_10TickProcess()       \
    {                                 \
        _Polsys_TickCount++;          \
        if (_Polsys_TickCount == 10)  \
        {                             \
            _Polsys_Do10TickTask();   \
            _Polsys_TickCount = 0;    \
            _Polsys_100TickProcess(); \
        }                             \
    }
#else
#define _Polsys_10TickProcess()
#endif

// APIs

#define Polsys_Init()        \
    {                        \
        _Polsys_ClockInit(); \
        _Polsys_TickStart(); \
        Polsys_EnableInt();  \
    }

// 请在定时器中断中调用此函数
#define Polsys_Tick()           \
    {                           \
        _Polsys_mTicked = true; \
    }

// 在主循环中调用，用来执行各个任务
#define Polsys_Loop()                 \
    {                                 \
        _POLSYS_TASK_GROUP_LOOP;      \
        if (_Polsys_mTicked)          \
        {                             \
            _Polsys_mTicked = false;  \
            _POLSYS_TASK_GROUP_1TICK; \
            _Polsys_10TickProcess();  \
        }                             \
    }

#else

//自定义数据类型

// 任务状态
typedef enum _task_status
{
    TS_WAIT = 0, // 执行时间未到
    TS_READY     // 执行时间已经到了，即将被执行
} task_status_t;

// task “类”
typedef struct _polsys_task
{
    void (*EntryFunc)(void);
    u16 Interval;
    u16 WaitTime;
    task_status_t Status;
} polsys_task_t;

// 提供的接口

void Polsys_Init();
void Polsys_Tick(); //在定时器中调用
void Polsys_Loop(); //在主循环调用
// 初始化一个任务，这个任务会被加入到任务列表
// task_ptr: 任务对象的地址，需要先静态定义一个task对象（polsys_task_t）
// Entry: 任务入口函数
// Interval: 执行间隔时间，以 POLSYS_TICK_CYCLE 为单位。
bool Polsys_TaskInit(polsys_task_t *task_ptr, void (*Entry)(void), u16 Interval);
// 动态创建一个任务。【待实现】
// polsys_task_t *Polsys_NewTask(void (*Entry)(void), u16 Interval);
// 动态删除一个任务，只能删除动态创建的任务。【待实现】
// Polsys_DeleteTask(polsys_task_t *task_ptr);
#endif

#include "polsys_cpts.h"

#endif
